package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

class Node {
    int data;
    Node next;

    public Node(int data) {
        this.data = data;
        this.next = null;
    }
}

public class Main {
//    static class Graph {
//        private final List<List<Integer>> adjList;
//
//        public Graph(int vertices) {
//            adjList = new ArrayList<>();
//            for (int i = 0; i < vertices; i++) {
//                adjList.add(new ArrayList<>());
//            }
//        }
//
//        public void addEdge(int v, int w) {
//            adjList.get(v).add(w);
//            adjList.get(w).add(v); // 无向图
//        }
//
//        public int bfs(int start, int end) {
//            boolean[] visited = new boolean[adjList.size()];
//            int[] distance = new int[adjList.size()];
//            Arrays.fill(distance, -1);
//
//            Queue<Integer> queue = new LinkedList<>();
//            queue.offer(start);
//            distance[start] = 0;
//
//            while (!queue.isEmpty()) {
//                int current = queue.poll();
//                if (current == end) {
//                    return distance[end]; // 跳数从0开始计数
//                }
//
//                for (int neighbor : adjList.get(current)) {
//                    if (!visited[neighbor]) {
//                        visited[neighbor] = true;
//                        distance[neighbor] = distance[current] + 1;
//                        queue.offer(neighbor);
//                    }
//                }
//            }
//
//            return -1; // 未找到路径
//        }
//    }
//
//    public static void main(String[] args) throws IOException {
//        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//
//        // 第一行包含两个整数n和m
//        String[] nm = reader.readLine().split(" ");
//        int n = Integer.parseInt(nm[0]); // IP 地址数量
//        int m = Integer.parseInt(nm[1]); // 连通关系数量
//
//        // 接下来n行，每行包含一个字符串和一个整数，表示一个IP地址和它的编号
//        Map<String, Integer> ipDict = new HashMap<>();
//        for (int i = 0; i < n; i++) {
//            String[] line = reader.readLine().split(" ");
//            String ip = line[0];
//            int id = Integer.parseInt(line[1]) - 1; // 编号从0开始
//            ipDict.put(ip, id);
//        }
//
//        // 构建图
//        Graph graph = new Graph(n);
//        for (int i = 0; i < m; i++) {
//            String[] ab = reader.readLine().split(" ");
//            int a = Integer.parseInt(ab[0]) - 1; // 编号从0开始
//            int b = Integer.parseInt(ab[1]) - 1; // 编号从0开始
//            graph.addEdge(a, b);
//        }
//
//        // 接下来一行包含一个整数q
//        int q = Integer.parseInt(reader.readLine()); // 需要判断连通性的IP地址数量
//
//        // 接下来q行，每行包含两个字符串，表示需要判断连通性的两个IP地址
//        for (int i = 0; i < q; i++) {
//            String[] query = reader.readLine().split(" ");
//            int start = ipDict.get(query[0]);
//            int end = ipDict.get(query[1]);
//            System.out.println(graph.bfs(start, end));
//        }
//    }


//    public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
//
//        // 读取初始位置 (a, b) 和目标位置 (c, d)
//        int a = scanner.nextInt();
//        int b = scanner.nextInt();
//        int c = scanner.nextInt();
//        int d = scanner.nextInt();
//
//        // 读取瓶子的数量 n
//        int n = scanner.nextInt();
//
//        // 记录总的最小代价
//        int totalCost = 0;
//
//        // 读取每个瓶子的位置 (x, y) 并计算代价
//        for (int i = 0; i < n; i++) {
//            int x = scanner.nextInt();
//            int y = scanner.nextInt();
//
//            // 计算从 (a, b) 移动到 (x, y) 的代价
//            int moveToBottleCost = Math.abs(x - a) + Math.abs(y - b);
//
//            // 计算从 (x, y) 移动到 (c, d) 的代价
//            int moveToTargetCost = Math.abs(x - c) + Math.abs(y - d);
//
//            // 累加代价
//            totalCost += (moveToBottleCost + moveToTargetCost);
//
//            // 更新小美的当前位置为当前瓶子的位置
//            a = x;
//            b = y;
//        }
//
//        // 输出总的最小代价
//        System.out.println(totalCost);
//
//        // 关闭扫描器
//        scanner.close();
//    }




//    public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
//
//        // 读取人数 n 和商品数量 m
//        int n = scanner.nextInt();
//        int m = scanner.nextInt();
//
//        // 读取商品的保质期
//        int[] expiryDates = new int[m];
//        for (int i = 0; i < m; i++) {
//            expiryDates[i] = scanner.nextInt();
//        }
//
//        // 读取商品的类型
//        int[] types = new int[m];
//        for (int i = 0; i < m; i++) {
//            types[i] = scanner.nextInt();
//        }
//
//        // 初始化商品库存状态，1 表示有货，0 表示售罄
//        boolean[] available = new boolean[m];
//        Arrays.fill(available, true);
//
//        // 处理每个人的需求
//        for (int person = 0; person < n; person++) {
//            int l = scanner.nextInt() - 1; // 转换为0基索引
//            int r = scanner.nextInt() - 1; // 转换为0基索引
//            int targetType = scanner.nextInt();
//            int k = scanner.nextInt();
//
//            // 收集符合条件的商品
//            List<Integer> candidates = new ArrayList<>();
//            for (int i = l; i <= r; i++) {
//                if (available[i] && types[i] == targetType) {
//                    candidates.add(i);
//                }
//            }
//
//            // 按照保质期从大到小排序（保质期相同的情况下，编号较小的优先）
//            candidates.sort((i1, i2) -> {
//                if (expiryDates[i1] != expiryDates[i2]) {
//                    return Integer.compare(expiryDates[i2], expiryDates[i1]); // 保质期大优先
//                } else {
//                    return Integer.compare(i1, i2); // 编号小优先
//                }
//            });
//
//            // 如果有足够的商品，输出商品编号并更新库存
//            if (candidates.size() >= k) {
//                // 输出前 k 个商品的编号
//                for (int i = 0; i < k; i++) {
//                    available[candidates.get(i)] = false; // 标记商品为已售罄
//                    System.out.print((candidates.get(i) + 1) + " "); // 输出商品编号，转换为1基索引
//                }
//                System.out.println();
//            } else {
//                System.out.println(-1); // 没有足够的商品
//            }
//        }
//
//        scanner.close();
//    }

//    public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
//
//        // 读取输入的行数和列数
//        int rows = scanner.nextInt();
//        int cols = scanner.nextInt();
//
//        // 读取图案
//        char[][] pattern = new char[rows][cols];
//        for (int i = 0; i < rows; i++) {
//            String line = scanner.next();
//            for (int j = 0; j < cols; j++) {
//                pattern[i][j] = line.charAt(j);
//            }
//        }
//
//        // 检查左右对称
//        boolean isLeftRightSymmetric = checkLeftRightSymmetry(pattern);
//        // 检查上下对称
//        boolean isTopBottomSymmetric = checkTopBottomSymmetry(pattern);
//
//        // 输出结果
//        System.out.println(isLeftRightSymmetric ? "YES" : "NO");
//        System.out.println(isTopBottomSymmetric ? "YES" : "NO");
//
//        scanner.close();
//    }
//
//    private static boolean checkLeftRightSymmetry(char[][] pattern) {
//        int rows = pattern.length;
//        int cols = pattern[0].length;
//
//        for (int i = 0; i < rows; i++) {
//            for (int j = 0; j < cols / 2; j++) {
//                if (pattern[i][j] != pattern[i][cols - 1 - j]) {
//                    return false;
//                }
//            }
//        }
//        return true;
//    }
//
//    private static boolean checkTopBottomSymmetry(char[][] pattern) {
//        int rows = pattern.length;
//        int cols = pattern[0].length;
//
//        for (int i = 0; i < rows / 2; i++) {
//            for (int j = 0; j < cols; j++) {
//                if (pattern[i][j] != pattern[rows - 1 - i][j]) {
//                    return false;
//                }
//            }
//        }
//        return true;
//    }

//    public static void main(String[] args) {
//        Scanner scanner = new Scanner(System.in);
//
//        // 读取函数名的数量
//        int count = scanner.nextInt();
//        scanner.nextLine(); // 消耗换行符
//
//        // 处理每个函数名
//        for (int i = 0; i < count; i++) {
//            String functionName = scanner.nextLine();
//            System.out.println(convertFunctionName(functionName));
//        }
//
//        scanner.close();
//    }

//    private static String convertFunctionName(String functionName) {
//        // 检查是否已经是下划线命名法
//        if (functionName.contains("_")) {
//            return functionName;
//        }
//
//        // 尝试转换为下划线命名法
//        StringBuilder convertedName = new StringBuilder();
//        boolean foundUppercase = false;
//        for (int i = 0; i < functionName.length(); i++) {
//            char ch = functionName.charAt(i);
//            if (Character.isUpperCase(ch)) {
//                if (foundUppercase && convertedName.length() > 0) {
//                    convertedName.append('_');
//                }
//                foundUppercase = true;
//                convertedName.append(Character.toLowerCase(ch));
//            } else {
//                convertedName.append(ch);
//                foundUppercase = false;
//            }
//        }
//
//        // 检查是否为小驼峰命名法
//        if (convertedName.length() > 0 && Character.isLowerCase(functionName.charAt(0))) {
//            return convertedName.toString();
//        }
//
//        // 如果既不是小驼峰命名法也不是下划线命名法
//        return "indistinct";
//    }
//    public static int countGoodPairs(int n, int[] p) {
//        // 创建一个数组用于计数，大小为 2n + 1，因为和的范围是从 2 到 2n + 1
//        int[] count = new int[2 * n + 1];
//        int result = 0;
//
//        // 遍历数组，记录每个和的出现次数
//        for (int i = 0; i < n; i++) {
//            int sum = (i + 1) + p[i]; // 计算 i+1 与 p[i] 的和
//            if (sum >= 1 && sum <= 2 * n) {
//                count[sum]++; // 增加这个和的计数
//            }
//        }
//
//        // 再次遍历数组，统计符合条件的对数
//        for (int i = 0; i < n; i++) {
//            int diff = (i + 1) - p[i]; // 计算 i+1 与 p[i] 的差值
//            if (diff >= 1 && diff <= 2 * n) {
//                result += count[diff]; // 加上之前出现的匹配次数
//            }
//        }
//
//        return result;
//    }
//
//    public static void main(String[] args){
//        Scanner scanner = new Scanner(System.in);
//        int n = scanner.nextInt();
//        int[] p = new int[n];
//        for (int i = 0; i < n; i++) {
//            p[i] = scanner.nextInt();
//        }
//        int result = countGoodPairs(n, p);
//        System.out.println(result);
//        scanner.close();
//    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 读取组数
        int T = scanner.nextInt();
        scanner.nextLine(); // 消耗换行符

        while (T-- > 0) {
            // 读取每组数据的行数
            int n = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符

            // 构建链表
            Node head = null;
            Node current = null;
            for (int i = 0; i < n; i++) {
                String[] parts = scanner.nextLine().split(" ");
                int a = Integer.parseInt(parts[0]);
                int b = Integer.parseInt(parts[1]);

                Node newNode = new Node(a);

                // 如果是第一个节点，设置为头节点
                if (head == null) {
                    head = newNode;
                    current = head;
                } else {
                    current.next = newNode;
                    current = newNode;
                }

                // 如果 b 不为 0，记录下一个节点的位置
                if (b != 0) {
                    // 使用 LinkedList 作为辅助数据结构来记录位置
                    LinkedList<Node> positions = new LinkedList<>();
                    positions.add(current);
                    for (int j = 1; j < b; j++) {
                        current = current.next;
                        positions.add(current);
                    }
                    current.next = newNode;
                    for (Node pos : positions) {
                        pos.next = current;
                    }
                }
            }

            // 逆序输出链表
            LinkedList<Integer> list = new LinkedList<>();
            current = head;
            while (current != null) {
                list.addFirst(current.data);
                current = current.next;
            }

            // 打印结果
            for (int num : list) {
                System.out.print(num + (num != list.getLast() ? " " : ""));
            }
            System.out.println();
        }

        scanner.close();
    }

//5 5
//2 3 4 5 6
//1 1 0 1 1
//1 3 1 2
//1 3 1 2
//1 3 0 5
//1 5 1 1
//1 5 0 1
}